home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-03-02 | 18.2 KB | 555 lines | [TEXT/MPS ] |
- /*------------------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # MultiFinder-Aware Simple TextEdit Sample Application
- #
- # CPlusTESample
- #
- # TEDocument.cp - C++ source
- #
- # Copyright © 1989 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions:
- # 1.10 07/89
- # 1.00 04/89
- #
- # Components:
- # CPlusTESample.make July 9, 1989
- # TApplicationCommon.h July 9, 1989
- # TApplication.h July 9, 1989
- # TDocument.h July 9, 1989
- # TECommon.h July 9, 1989
- # TESample.h July 9, 1989
- # TEDocument.h July 9, 1989
- # TApplication.cp July 9, 1989
- # TDocument.cp July 9, 1989
- # TESample.cp July 9, 1989
- # TEDocument.cp July 9, 1989
- # TESampleGlue.a July 9, 1989
- # TApplication.r July 9, 1989
- # TESample.r July 9, 1989
- #
- # CPlusTESample is an example application that demonstrates
- # how to initialize the commonly used toolbox managers,
- # operate successfully under MultiFinder, handle desk
- # accessories and create, grow, and zoom windows. The
- # fundamental TextEdit toolbox calls and TextEdit autoscroll
- # are demonstrated. It also shows how to create and maintain
- # scrollbar controls.
- #
- # This version of TESample has been substantially reworked in
- # C++ to show how a "typical" object oriented program could
- # be written. To this end, what was once a single source code
- # file has been restructured into a set of classes which
- # demonstrate the advantages of object-oriented programming.
- #
- ------------------------------------------------------------------------------*/
-
-
- /*
- Segmentation strategy:
-
- This program has only one segment, since the issues
- surrounding segmentation within a class's methods have
- not been investigated yet. We DO unload the data
- initialization segment at startup time, which frees up
- some memory
-
- SetPort strategy:
-
- Toolbox routines do not change the current port. In
- spite of this, in this program we use a strategy of
- calling SetPort whenever we want to draw or make calls
- which depend on the current port. This makes us less
- vulnerable to bugs in other software which might alter
- the current port (such as the bug (feature?) in many
- desk accessories which change the port on OpenDeskAcc).
- Hopefully, this also makes the routines from this
- program more self-contained, since they don't depend on
- the current port setting.
-
- Clipboard strategy:
-
- This program does not maintain a private scrap.
- Whenever a cut, copy, or paste occurs, we import/export
- from the public scrap to TextEdit's scrap right away,
- using the TEToScrap and TEFromScrap routines. If we did
- use a private scrap, the import/export would be in the
- activate/deactivate event and suspend/resume event
- routines.
- */
-
- // Mac Includes
- #include <Types.h>
- #include <Quickdraw.h>
- #include <Fonts.h>
- #include <Controls.h>
- #include <Windows.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Menus.h>
- #include <Devices.h>
- #include <Events.h>
- #include <Scrap.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <Traps.h>
- #include <LowMem.h>
- #include <Controls.h>
- #include <TextUtils.h>
- #include <MacTextEditor.h>
-
- #include "MLTEDocument.h"
- // we need resource definitions
- #include "TECommon.h"
-
- // #include "TESample.h"
-
- //change 1 remove the control functions
-
- // kTextMargin is the number of pixels we leave blank at the edge of the window.
- const short kTextMargin = 2;
-
- // kMaxDocWidth is an arbitrary number used to specify the width of the TERec's
- // destination rectangle so that word wrap and horizontal scrolling can be
- // demonstrated.
- const short kMaxDocWidth = 576;
-
- // kMinDocDim is used to limit the minimum dimension of a window when GrowWindow
- // is called.
- //change: remove kMinDocDim
-
- // kMaxTELength is an arbitrary number used to limit the length of text in the TERec
- // so that various errors won't occur from too many characters being in the text.
- // change: remove kMaxTELength
-
- // kControlInvisible is used the same way to 'turn on' the control.
- // change 2 remove kControlVisible
-
- // ScrollBarAdjust, GrowBoxAdjust, and ScrollBar width are used in calculating
- // values for control positioning and sizing.
- // change 3 remove the constants associated with scrolling and the Growbox
-
- // kTESlop provides some extra security when pre-flighting edit commands.
- // change 4 remove the kTESlop
-
- // kScrollTweek compensates for off-by-one requirements of the scrollbars
- // to have borders coincide with the growbox.
- // change 5 remove the kScrollTweek
-
- // kCrChar is used to match with a carriage return when calculating the
- // number of lines in the TextEdit record. kDelChar is used to check for
- // delete in keyDowns.
- // change 6 remove kCrChar and kDelChar
-
- // Use universal procedure pointers that are compatible with both 68K and PowerPC.
- // change 7 remove the procedure pointers
- Boolean inited = false;
-
-
- /***********************************************************************/
- //
- // TEDocument class declarations
- //
- /***********************************************************************/
-
- //-----------------------------------------------------------------------
- // TEDocument::TEDocument - notice that we pass the resID parameter up to our
- // base class, which actually creates the window for us.
- // If you modify this so that it doesn't create a
- // window, be sure to take that into account in the
- // application class so that it doesn't believe an
- // error occurred (as version 1.20 of TApplication
- // would).
- //
- TEDocument::TEDocument( short resID ) : TDocument( resID )
- {
- //change remove good
- //change remove Rect destRect, viewRect;
- OSStatus status; //change add an OSStatus
-
- // initialize routine desciptors once
- if (!inited)
- {
- // change 8 remove the calls to NewControlActionProc
- // and NewTEClickLoopProc
- inited = true;
- }
-
- SetPort( fDocWindow );
- //change 8 remove the call to GetTERect which we don't need anymore
- //and the rectangle manipulations
-
- //change 9 replace call to TENew with a call to TXNNewObject
- status = TXNNewObject(
- NULL, /* can be NULL */
- fDocWindow,
- NULL, /* can be NULL */
- kTXNShowWindowMask|kTXNWantHScrollBarMask|kTXNWantVScrollBarMask|kTXNSaveStylesAsSTYLResourceMask|kTXNDrawGrowIconMask,
- kTXNTextEditStyleFrameType, /* the only valid option */
- kTXNTextFile,
- kTXNSystemDefaultEncoding,
- &fMLTEObject,
- &fMLTEFrameID,
- NULL
- );
-
- //change use of fDocTE to fMLTEObject and test the function result
- //also remove all the control calls and the call to TEAutoView
- if ( fMLTEObject == NULL || status != noErr ) // if TENew succeeded, we have a good document
- AlertUser( kTEDocErrStrings, eNoWindow ); // tell user we failed
-
- } /* TEDocument (constructor) */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::~TEDocument - At this point, if there was a document associated
- // with a window, you could do any document saving
- // processing if it is 'dirty'. DoCloseWindow would
- // return true if the window actually closed, i.e.,
- // the user didn’t cancel from a save dialog. This
- // result is handy whenthe user quits an application,
- // but then cancels the save of a documentassociated
- // with a window.
- //
- TEDocument::~TEDocument(void)
- {
- HideWindow( fDocWindow );
-
- // get rid of any extra storage that was used for the window
- // change for this do a TXNDeleteObject
- if ( fMLTEObject != nil )
- TXNDeleteObject(fMLTEObject); // dispose the TEHandle if we got far enough to make one
-
- //change no more reason to call DisposeControl
-
- // base class destructor will dispose of window
- } /* TEDocument (destructor) */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoZoom -
- //
- void TEDocument::DoZoom( short partCode )
- {
- //change replace the guts of this whole function with a call to TXNZoomWindow
- TXNZoomWindow( fMLTEObject,partCode);
-
- } /* TEDocument::DoZoom */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoGrow - Called when a mouseDown occurs in the grow box of
- // an active window.
- //
- void TEDocument::DoGrow( EventRecord* theEvent )
- {
- //change replace the guts of this function with a call to TXNGrowWindow
- TXNGrowWindow( fMLTEObject, theEvent );
- } /* TEDocument::DoGrow */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoContent -
- //
- void TEDocument::DoContent( EventRecord* theEvent )
- {
- //change replace the guts with a call to TXNClick
- TXNClick(fMLTEObject,theEvent);
- } /* TEDocument::DoContent */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoKeyDown -
- //
- void TEDocument::DoKeyDown( EventRecord* theEvent )
- {
- //replace the guts of this routine with a call to TXNKeyDown
- TXNKeyDown ( fMLTEObject, theEvent );
-
- } /* TEDocument::DoKeyDown */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoActivate -
- //
- void TEDocument::DoActivate( Boolean becomingActive )
- {
- //change replace all this with a call to TXNFocus followed by a call to TXNActivate
- TXNFocus( fMLTEObject, becomingActive );
- TXNActivate( fMLTEObject, fMLTEFrameID, becomingActive);
-
- } /* TEDocument::DoActivate */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoUpdate -
- //
- void TEDocument::DoUpdate(void)
- {
- //change: replace all this with a call to TXNUpdate. TXNUpdate calls BeginUpdate/EndUpdate
- //and handles drawing the scroll bars.
- TXNUpdate ( fMLTEObject );
-
- } /* TEDocument::DoUpdate */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::CalcIdle - calculate how much idle time we need
- //
- unsigned long TEDocument::CalcIdle(void)
- {
- //change: replace all this with a call to TXNGetSleepTicks
- return TXNGetSleepTicks( fMLTEObject );
-
- } /* TEDocument::CalcIdle */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoIdle - This is called whenever we get a null event et al.
- // It takes care of necessary periodic actions. For
- // this program, it calls TEIdle.
- //
- void TEDocument::DoIdle( void )
- {
- //change: replace TEIdle with a call to TXNIdle
-
- TXNIdle(fMLTEObject);
-
-
- } /* TEDocument::DoIdle */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DrawWindow - Draw the contents of an application window.
- //
- //change: completely remove the call the method DrawWindow
-
-
- //-----------------------------------------------------------------------
- // TEDocument::GetTERect - Return a rectangle that is inset from the portRect
- // by the size of the scrollbars and a little extra margin.
- //
- //change: completely remove the method ::GetTERect
-
-
- //-----------------------------------------------------------------------
- // TEDocument::GetVisTERgn - setup a region which contains the visible text
- //
- //change: completely remove the call the method GetVisTERgn
-
-
- //-----------------------------------------------------------------------
- // TEDocument::HaveSelection - Return boolean value indicating that there is
- // or is not a selection in the document
- //
- //change: completely remove the method HaveSelection
- Boolean TEDocument::HaveSelection()
- {
- //replace guts with TXNIsSelectionEmpty
- return !TXNIsSelectionEmpty( fMLTEObject );
-
- } /* TEDocument::HaveSelection */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::AdjustViewRect - Update the TERec's view rect so that it is the
- // greatest multiple ofthe line Height that still
- // fits in the old viewRect.
- //
- //change: completely remove the method AdjustViewRect
-
-
- //-----------------------------------------------------------------------
- // TEDocument::AdjustTE - Scroll the TERec around to match up to the potentially
- // updated scrollbar values. This is really useful when
- // the window has been resized such that the scrollbars
- // became inactive but the TERec was already scrolled.
- //
- //change: completely remove the method AdjustTE
-
-
- //-----------------------------------------------------------------------
- // TEDocument::AdjustScrollSizes - Re-calculate the position and size of the
- // viewRect and the scrollbars. kScrollTweek
- // compensates for off-by-one requirements of
- // the scrollbars to have borders coincide
- // with the growbox.
- //
- //change: completely remove the method AdjustScrollSizes
-
-
- //-----------------------------------------------------------------------
- // TEDocument::AdjustScrollbars - Turn off the controls by jamming a zero into
- // their contrlVis fields (HideControl erases them
- // and we don't want that). If the controls are to
- // be resized as well, call the procedure to do that,
- // then call the procedure to adjust the maximum and
- // current values. Finally re-enable the controls by
- // jamming a $FF in their contrlVis fields (ShowControl
- // re-draws the control, which may not be necessary).
- //
- //change: completely remove the method AdjustScrollbars
-
- // Calculate the new control maximum value and current value, whether it is the horizontal or
-
- //-----------------------------------------------------------------------
- // TEDocument::AdjustHV - Turn off the controls by jamming a zero into vertical
- // scrollbar. The vertical max is calculated by comparing
- // the number of lines to the vertical size of the viewRect.
- // The horizontal max is calculated by comparing the
- // maximum document width to the width of the viewRect.
- // The current values are set by comparing the offset
- // between the view and destination rects. If necessary,
- // redraw the control by calling ShowControl.
- //
- //change: completely remove the method AdjustHV
-
- //-----------------------------------------------------------------------
- // TEDocument::AdjustScrollValues - Simply call the common adjust routine for
- // the vertical and horizontal scrollbars.
- //
- //change: completely remove the method AdjustScrollValues
-
-
- //-----------------------------------------------------------------------
- // TEDocument::GetClickLoop -
- //
- //change: completely remove the method GetClickLoop
-
-
- //-----------------------------------------------------------------------
- // TEDocument::GetTEHandle -
- //
- //change: make GetTEHandle into GetMLTEObject
- TXNObject TEDocument::GetMLTEObject( void )
- {
- return fMLTEObject;
-
- } /* TEDocument::GetTEHandle */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoCut -
- //
- void TEDocument::DoCut( void )
- {
- //change: replace the guts of this with TXNCut
- //notice that TXNCut does return a status which we
- //are ignoring here.
- (void)TXNCut( fMLTEObject );
-
- } /* TEDocument::DoCut */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoCopy -
- //
- void TEDocument::DoCopy( void )
- {
- //change: replace the guts of this with a call to TXNCopy
- //again TXNCopy returns an OSStatus which we are ignoring
- (void)TXNCopy( fMLTEObject );
-
- } /* TEDocument::DoCopy */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoPaste -
- //
- void TEDocument::DoPaste( void )
- {
- //change: replace the guts with a call to TXNPaste
- //once again ignoring the status
- (void)TXNPaste ( fMLTEObject );
-
- } /* TEDocument::DoPaste */
-
-
- //-----------------------------------------------------------------------
- // TEDocument::DoClear -
- //
- void TEDocument::DoClear( void )
- {
- //change: replace the guts with a call to TXNClear
- //ignore the status
- TXNClear( fMLTEObject );
-
- } /* TEDocument::DoClear */
-
-
-
- /***********************************************************************/
- //
- // Global declarations
- // Routines used by this class, which don't belong to the class since we use
- // them as toolbox filter routines, and you cannot pass class methods as ProcPtrs.
- //
- /***********************************************************************/
-
-
- //-----------------------------------------------------------------------
- // CommonAction - Common algorithm for pinning the value of a control.
- // It returns the actual amount the value of the control
- // changed.
- //
- //change: completely remove function CommonAction
-
-
- //-----------------------------------------------------------------------
- // VActionProc - Determines how much to change the value of the vertical
- // scrollbar by and how much to scroll the TE record.
- //
- //change: completely remove VActionProc
-
-
- //-----------------------------------------------------------------------
- // HActionProc - Determines how much to change the value of the horizontal
- // scrollbar by and how much to scroll the TE record.
- //
- //change: completely remove HActionProc
-
-
- //-----------------------------------------------------------------------
- // PascalClickLoop -Gets called from our assembly language routine (on the
- // 68K, C on the PowerPC), ASMCLICKLOOP,
- // which is in turn called by the TEClick toolbox routine.
- // Saves the windows clip region, sets it to the portRect,
- // adjusts the scrollbar values to match the TE scroll amount,
- // then restores the clip region.
- //
- //change: completely remove PascalClickLoop
-
-
- //-----------------------------------------------------------------------
- // GetOldClickLoop -Gets called from our assembly language routine (on the
- // 68K, C on the PowerPC), ASMCLICKLOOP,
- // which is in turn called by the TEClick toolbox routine. It
- // returns the address of the default ClickLoop routine that was
- // put into the TERec by TEAutoView to ASMCLICKLOOP so that it
- // can call it.
- //
- //change: completely remove TEClickLoopUPP
-
-
- //-----------------------------------------------------------------------
- // AlertUser -
- //
- void AlertUser( short errResID, short errCode )
- {
- Str255 message;
-
- SetCursor( &qd.arrow );
- GetIndString( message, errResID, errCode );
- ParamText( message,(ConstStr255Param) "\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p" );
- (void) Alert( rUserAlert, nil );
-
- } /* AlertUser */
-
- //change: completely remove ASMCLICKLOOP
-